iT邦幫忙

2024 iThome 鐵人賽

DAY 10
0

每天的專案會同步到 GitLab 上,可以前往 GitLab 查看。
有興趣的朋友歡迎留言 or 來信討論,我的信箱是 nickchen1998@gmail.com

因為 Pinecone 免費版只能建立一組索引庫,為了避免每次效果混淆,每次都會把資料清除後再重新建立索引庫。

PyMuPDFLoader 讀取 PDF 文件

PDF 作為一班企業做常使用的文件檔,LangChain 當然也有協助我們包好可以使用的 Loader,這次的範例當中我們會使用 勞動基準法 來作為範例展示。

下面的範例是使用 pymupdf 以頁為單位截取出內容的範例:

pip install pymupdf

from pprint import pprint
from env_settings import BASE_DIR
from langchain_community.document_loaders import PyMuPDFLoader

loader = PyMuPDFLoader(file_path=BASE_DIR / "勞動基準法.pdf")
pprint(loader.load())

可以看到 LangChain 不僅協助我們把 PDF 的內容以及 metadata 讀取出來,也同時協助我們轉換成寫入用的 Document 物件了!

pdf_content_without_chunk

寫入向量並查詢

話不多說,我們馬上使用第八天的方式來把剛剛讀取出來的 Document 物件寫入向量庫:

from env_settings import EnvSettings, BASE_DIR
from langchain_community.document_loaders import PyMuPDFLoader
from langchain_openai.embeddings import OpenAIEmbeddings
from langchain_pinecone import PineconeVectorStore
from pinecone import Pinecone

loader = PyMuPDFLoader(file_path=BASE_DIR / "勞動基準法.pdf")

# 寫入向量
env_settings = EnvSettings()
embedding = OpenAIEmbeddings(
    openai_api_key=env_settings.OPENAI_API_KEY
)
vector_store = PineconeVectorStore(
    index=Pinecone(api_key=env_settings.PINECONE_API_KEY).Index("ithelp"),
    embedding=embedding
)
vector_store.add_documents(loader.load())

可以看到下圖中,我們成功將 metadata 以及 text 寫入向量資料庫當中:

page_base_index

接著讓我們使用下面的程式碼來試著查詢一下:

from env_settings import EnvSettings, BASE_DIR
from langchain_community.document_loaders import PyMuPDFLoader
from langchain_openai.embeddings import OpenAIEmbeddings
from langchain_pinecone import PineconeVectorStore
from pinecone import Pinecone

loader = PyMuPDFLoader(file_path=BASE_DIR / "勞動基準法.pdf")

# 寫入向量
env_settings = EnvSettings()
embedding = OpenAIEmbeddings(
    openai_api_key=env_settings.OPENAI_API_KEY
)
vector_store = PineconeVectorStore(
    index=Pinecone(api_key=env_settings.PINECONE_API_KEY).Index("ithelp"),
    embedding=embedding
)

res = vector_store.similarity_search(
    "勞工滿一年會有幾天特休?",
    k=1
)
print(res[0].page_content)

下圖中可以看到我們搜尋出來的結果:

without_split_content

串接搜尋結果以及問題

在拿到搜尋結果之後,我們可以使用下面的程式碼來將搜尋結果以及問題串接起來:

from env_settings import EnvSettings
from langchain_openai.embeddings import OpenAIEmbeddings
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_pinecone import PineconeVectorStore
from pinecone import Pinecone


# 建立 Vector 物件處理向量
env_settings = EnvSettings()
vector_store = PineconeVectorStore(
    index=Pinecone(api_key=env_settings.PINECONE_API_KEY).Index("ithelp"),
    embedding=OpenAIEmbeddings(
        openai_api_key=env_settings.OPENAI_API_KEY
    )
)

# 依靠問題查出相關段落
question = "勞工工作滿一年有幾天特休?"
documents = vector_store.similarity_search(question, k=1)

# 建立 chain 並回答問題
prompt = ChatPromptTemplate.from_template(
    """
    原始問題: {question}
    取得的參考資料: {data}
    """,
)
llm = ChatOpenAI(
    api_key=env_settings.OPENAI_API_KEY,
    model_name="gpt-4o"
)
chain = prompt | llm
result = chain.invoke({"question": question, "data": documents[0].page_content})
print(result.content)

下圖結果為 GPT 協助我們依照找出的段落彙整出的答案:

gpt_answer

內容預告

今天我們實際串接了一次 RAG 的基本流程給大家看,明天我們會介紹資料型態的檔案該如何進行處理,會以 JSON 格式為範例,有興趣的朋友可以提前準備一份資料!


上一篇
Day 09 - RAG 介紹
下一篇
Day 11 - DataToWord 套件介紹
系列文
初探 Langchain 與 LLM:打造簡易問診機器人13
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言